﻿using System;
using static System.Net.WebRequestMethods;

namespace app1_mycalculator
{
    public partial class Form1 : Form
    {

        bool complete = true;//判断是否第一次或完成一次运算
        double finalResult = 0;

        public Form1()
        {
            InitializeComponent();
            this.KeyPreview = true;
            this.KeyDown += txtInput_KeyDown;
            this.ActiveControl = txtInput;
        }

        private void btn_clr_Click(object sender, EventArgs e)
        {
            txtInput.Text = "";
            finalResult = 0;
        }

        private void btn_num1_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "1";
        }

        private void btn_num2_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "2";
        }

        private void btn_num3_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "3";
        }

        private void btn_num4_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "4";
        }

        private void btn_num5_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "5";
        }

        private void btn_num6_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "6";
        }

        private void btn_num7_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "7";
        }

        private void btn_num8_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "8";
        }

        private void btn_num9_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "9";
        }

        private void btn_plus_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = finalResult.ToString();
                complete = false;
            }
            txtInput.Text += "+";
        }

        private void btn_sub_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = finalResult.ToString();
                complete = false;
            }
            txtInput.Text += "-";
        }

        private void btn_mul_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = finalResult.ToString();
                complete = false;
            }
            txtInput.Text += "×";
        }

        private void btn_div_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = finalResult.ToString();
                complete = false;
            }
            txtInput.Text += "÷";
        }

        private void btnLeft_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                txtInput.Text = "";
                complete = false;
            }
            txtInput.Text += "(";
        }

        private void btnRight_Click(object sender, EventArgs e)
        {
            if (complete)
            {
                return;
            }
            txtInput.Text += ")";
        }

        private void btn_eq_Click(object sender, EventArgs e)
        {
            ExecuteOperation();
        }

        private void ExecuteOperation()
        {
            //获取计算框内现有字符
            string expression = txtInput.Text;
            //如果表达式为空
            if (expression.Length == 0)
            {
                txtInput.Text = "";
                return;
            }
            //使用栈结构处理数字及符号
            Stack<double> values = new Stack<double>();
            Stack<char> ops = new Stack<char>();

            for (int i = 0; i < expression.Length; i++)
            {
                if (Char.IsDigit(expression[i]))
                {
                    int j = i;
                    while ((j < expression.Length) && Char.IsDigit(expression[j]))
                        j++;
                    values.Push(Convert.ToDouble(expression.Substring(i, j - i)));
                    i = j - 1;
                }
                else if (expression[i] == '(')
                {
                    ops.Push(expression[i]);
                }
                else if (expression[i] == ')')
                {
                    while (ops.Count > 0 && ops.Peek() != '(')
                    {
                        values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop()));
                    }
                    ops.Pop(); // pop '('  
                }
                else if (IsOperator(expression[i]))
                {
                    while ((ops.Count > 0) && (Precedence(ops.Peek()) >= Precedence(expression[i])))
                    {
                        values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop()));
                    }
                    ops.Push(expression[i]);
                }
            }

            while (ops.Count > 0)
            {
                values.Push(ApplyOp(ops.Pop(), values.Pop(), values.Pop()));
            }

            finalResult = values.Pop();

            txtInput.Text += $"={finalResult.ToString()}";
            txtHistory.Text += $"\r\n{txtInput.Text}";
            complete = true;
        }

        private bool IsOperator(char op)
        {
            return op == '+' || op == '-' || op == '×' || op == '÷';
        }

        private int Precedence(char op)
        {
            if (op == '×' || op == '÷')
                return 2;
            if (op == '+' || op == '-')
                return 1;
            return 0;
        }

        private double ApplyOp(char op, double b, double a)
        {
            switch (op)
            {
                case '+':
                    return Calculator.Add(a, b);
                case '-':
                    return Calculator.Sub(a, b);
                case '×':
                    return Calculator.Mul(a, b);
                case '÷':
                    if (b == 0)
                        throw new DivideByZeroException("Cannot divide by zero.");
                    return Calculator.Div(a, b);
            }
            return 0;
        }

        private void txtInput_KeyDown(object sender, KeyEventArgs e)
        {
            // 检查是否按下了数字键  
            if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
            {
                if (complete)
                {
                    txtInput.Text = "";
                    complete = false;
                }
                // 按下的是数字0-9之间的键  
                int num = e.KeyCode - Keys.D0;
                txtInput.Text += num.ToString();
            }
            else if (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
            {
                if (complete)
                {
                    txtInput.Text = "";
                    complete = false;
                }
                // 按下的是数字小键盘上的0-9之间的键  
                int num = e.KeyCode - Keys.NumPad0;
                txtInput.Text += num.ToString();
            }
            else if (e.KeyCode == Keys.Add)
            {
                if (complete)
                {
                    txtInput.Text = finalResult.ToString();
                    complete = false;
                }
                txtInput.Text += "+";
            }
            else if (e.KeyCode == Keys.Subtract)
            {
                if (complete)
                {
                    txtInput.Text = finalResult.ToString();
                    complete = false;
                }
                txtInput.Text += "-";
            }
            else if (e.KeyCode == Keys.Multiply)
            {
                if (complete)
                {
                    txtInput.Text = finalResult.ToString();
                    complete = false;
                }
                txtInput.Text += "×";
            }
            else if (e.KeyCode == Keys.Divide)
            {
                if (complete)
                {
                    txtInput.Text = finalResult.ToString();
                    complete = false;
                }
                txtInput.Text += "÷";
            }
            else if (e.KeyCode == Keys.Enter)
            {
                ExecuteOperation();
            }
        }
    }
}
